import numpy as np
import math as m

#Really basic and crude assert functions
def assert_scalar(x, y, maxdiff=0.00001):
	count = 0
	if m.fabs(x - y) > maxdiff:
		count += 1
		print 'Error:',x,'!=',y
	return count	

def assert_ary_1d(xs, ys, maxdiff=0.00001):
	count = 0
	error = 0
	maxerror = 0
	for n in np.arange(len(xs)):
		error = m.fabs(xs[n] - ys[n])
		if error > maxdiff: #if xs[n] != ys[n]:
			count+=1
			if count == 1:
				if error > maxerror:
					maxerror = error
				print 'Error: xs[',n,']=',xs[n],' != ys[',n,']=', ys[n]
	if count > 0:
		print 'Total number of errors is', count,'max difference is:', maxerror
	return count

def assert_ary_2d(xs, ys, maxdiff=0.00001):
	count = 0
	error = 0
	maxerror = 0
	for n1 in np.arange(len(xs)):
		for n2 in np.arange(len(xs[n1])):
			error = m.fabs(xs[n1][n2] - ys[n1][n2])
			if error > maxdiff: #if xs[n1][n2] != ys[n1][n2]:
				count+=1
				if count == 1:
					if error > maxerror:
						maxerror = error
					print 'Error: xs[',n1,'][',n2,']=',xs[n1][n2],' != ys[',n1,'][',n2,']=', ys[n1][n2]
	if count > 0:
		print 'Total number of errors is', count,'max difference is:', maxerror
	return count

def assert_ary_3d(xs, ys, maxdiff=0.00001):
	count = 0
	error = 0
	maxerror = 0
	for n1 in np.arange(len(xs)):
		for n2 in np.arange(len(xs[n1])):
			for n3 in np.arange(len(xs[n1][n2])):
				error = m.fabs(xs[n1][n2][n3] - ys[n1][n2][n3])
				if error > maxdiff: #if xs[n1][n2][n3] != ys[n1][n2][n3]:
					count+=1
					if count == 1:
						if error > maxerror:
							maxerror = error
						print 'Error: xs[',n1,'][',n2,'][',n3,']=',xs[n1][n2][n3],\
								' != ys[',n1,'][',n2,'][',n3,']=', ys[n1][n2][n3]
	if count > 0:
		print 'Total number of errors is', count,'max difference is:', maxerror
	return count

def assert_ary_4d(xs, ys, maxdiff=0.00001):
	count = 0
	for n1 in np.arange(len(xs)):
		for n2 in np.arange(len(xs[n1])):
			for n3 in np.arange(len(xs[n1][n2])):
				for n4 in np.arange(len(xs[n1][n2][n3])):
					if m.fabs(xs[n1][n2][n3][n4] - ys[n1][n2][n3][n4]) > maxdiff: #if xs[n1][n2][n3][n4] != ys[n1][n2][n3][n4]:
						count+=1
						if count == 1:
							print 'Error: xs[',n1,'][',n2,'][',n3,'][',n4,']=',xs[n1][n2][n3][n4],\
									' != ys[',n1,'][',n2,'][',n3,'][',n4,']=', ys[n1][n2][n3][n4]
	if count > 0:
		print 'Total number of errors is', count
	return count

def copy_1d(src, cuda=0):
	dst=np.zeros(np.shape(src), dtype=src.dtype, cuda=cuda)
	for n1 in np.arange(len(src)):
		dst[n1]=src[n1]

	return dst

def copy_2d(src, cuda=0):
	dst=np.zeros(np.shape(src), dtype=src.dtype, cuda=cuda)
	for n1 in np.arange(len(src)):
		for n2 in np.arange(len(src[n1])):			
			dst[n1][n2]=src[n1][n2]

	return dst

def copy_3d(src, cuda=0):
	dst=np.zeros(np.shape(src), dtype=src.dtype, cuda=cuda)
	for n1 in np.arange(len(src)):
		for n2 in np.arange(len(src[n1])):
			for n3 in np.arange(len(src[n1][n2])):
				dst[n1][n2][n3]=src[n1][n2][n3]

	return dst

def copy_4d(src, cuda=0):
	dst=np.zeros(np.shape(src), dtype=src.dtype, cuda=cuda)
	for n1 in np.arange(len(src)):
		for n2 in np.arange(len(src[n1])):
			for n3 in np.arange(len(src[n1][n2])):
				for n4 in np.arange(len(src[n1][n2][n3])):
					dst[n1][n2][n3][n4]=src[n1][n2][n3][n4]
	return dst

